import Tkinter
from Canvas import Canvas, Rectangle, Oval
from ControlLoopClient import *


WIDTH = 600
HEIGHT = 600

X_2_WIDTH_RATIO = 30
Y_2_HEIGHT_RATIO = 30

TIME_INTERVAL = 100

class ScaleBar:
	def setValue(self, value):
		coords = self.canvas.coords( self.value_rect )
		(x1,y1,x2,y2) = (self.x1, self.y1, self.x2, self.y2) 
		if self.orientation == 'v':
			coords[0], coords[1], coords[2] = x1, y1, x2
			coords[3] = y1 + (y2 - y1) * (value - self.min_value) / (self.max_value - self.min_value)
		elif self.orientation == 'h':
			coords[0], coords[1], coords[3] = x1, y1, y2
			coords[2] = x1 + (x2 - x1) * (value - self.min_value) / (self.max_value - self.min_value)
		self.canvas.coords( self.value_rect, coords[0], coords[1], coords[2], coords[3] )

	def __init__(self, canvas, x1, y1, x2, y2, orientation, min_value, max_value):
		self.min_value = min_value
		self.max_value = max_value
		self.canvas = canvas
		(self.x1, self.y1, self.x2, self.y2) = (x1,y1,x2,y2)
		self.bound_rect = Rectangle(canvas, x1, y1, x2, y2)
		if orientation == 'v':
        		self.value_rect = Rectangle(canvas, x1, 0.5 * (y1 + y2), x2, 0.5 * (y1 + y2))
        	else:
        		self.value_rect = Rectangle(canvas, 0.5 * (x1 + x2), y1, 0.5 * (x1 + x2), y2)        	
		self.orientation = orientation

class ControlLoopClientApplication:
	def _setFeedBackScaleBar(self, index, value):
		self.scale_bars[index].setValue(value)

	def _setPosition(self, x, y):
		coord_x = WIDTH/2 + x * X_2_WIDTH_RATIO
		coord_y = HEIGHT / 2 + y * X_2_WIDTH_RATIO
		self.canvas.coords(self.position_marker, coord_x-10, coord_y-10, coord_x+10, coord_y+10 )

	def refreshFeedBacks(self):
		x_output = float( self.channelx.output.getValue() )
		y_output = float( self.channely.output.getValue() )
		self._setFeedBackScaleBar( 0, x_output )
		self._setFeedBackScaleBar( 1, y_output )

	def refreshPosition(self):
		xx = self.channelx.input.getValue()
		yy = self.channely.input.getValue()
		x = float( xx )
		y = float( yy )
		self._setPosition(x, y)

	def setNewTarget(self, x, y):
		self.target_x = x
		self.target_y = y
		self.channelx.keep(x)
		self.channely.keep(y)		

	def onMouseClick(self, event):
		x = (1.0 * ( event.x - WIDTH/2 )) / X_2_WIDTH_RATIO
		y = (1.0 * ( event.y - HEIGHT/2 )) / Y_2_HEIGHT_RATIO

		self.canvas.coords(self.desired_target_marker, WIDTH/2 + x * X_2_WIDTH_RATIO - 3, HEIGHT/2+y * X_2_WIDTH_RATIO -3, WIDTH/2 + x * X_2_WIDTH_RATIO + 3, HEIGHT/2+y * X_2_WIDTH_RATIO + 3)
		self.setNewTarget(x, y)

	def onTimer(self):
		self.refreshFeedBacks()
		self.refreshPosition()
		root.after(TIME_INTERVAL, lambda : self.onTimer() )

	def __init__(self, root, control_loop_connection):
		self.channelx = control_loop_connection.channel['x']
		self.channely = control_loop_connection.channel['y']

		self.canvas = Canvas(root, bg="white", width=WIDTH, height=HEIGHT)
		self.canvas.pack();

		#Reuslt of regulationg bars
		self.scale_bars = [ScaleBar(self.canvas, 0.2*WIDTH,0.9*HEIGHT,0.8*WIDTH,0.95*HEIGHT,'h',-10,10), ScaleBar(self.canvas, 0.1*WIDTH,0.2*HEIGHT,0.15*WIDTH,0.8*HEIGHT,'v',-10,10)]

		#Actual system state marker
		self.position_marker = Oval(self.canvas, WIDTH/2 - 3, HEIGHT/2 - 3, WIDTH/2 + 3, HEIGHT/2 + 3)

		#Target system state marker
		self.target_x, self.target_y = 0, 0
		self.desired_target_marker = Oval(self.canvas, WIDTH/2 - 10, HEIGHT/2 - 10, WIDTH/2 + 10, HEIGHT/2 + 10)
		self.root = root
		root.bind("<Button-1>", lambda event: self.onMouseClick(event) )
		self.onTimer()

root = Tkinter.Tk()
root.title("Control loop demo control application")
control_loop_connection = ControlLoopTCPConnection()
control_loop_connection.connect( 'localhost', 12673 )
application = ControlLoopClientApplication( root, control_loop_connection )
root.mainloop()

